package com.shihan._01_multi_thread_basic.producer_consumer;

/**
 * @Description 公共队列（资源类）
 * @Author shihan
 * @Date 2021/8/10 7:30
 * @Version 1.0
 */
public class MyQueue {

    // 队列是一个数组，不可以扩容
    private String[] queue = new String[10];
    // 标识队列的总长度
    private int queueLength = 10;
    // 记录当前队列中，已有数据的个数
    private int currentValueSize = 0;
    // 下一次 put 的索引位置
    private int putIndex = 0;
    // 下一次 get 的索引位置
    private int getIndex = 0;

    /**
     * 往队列中 put 放数据
     *
     * @param value
     */
    public synchronized void put(String value) throws InterruptedException {
        // 如果队列已满，则阻塞
        while (currentValueSize == queueLength) {
            System.out.println(Thread.currentThread().getName() + "被阻塞");
            wait();
        }
        // 正常执行业务逻辑
        queue[putIndex] = value;
        putIndex++;
        currentValueSize++;
        if (putIndex >= queueLength) {
            putIndex = 0;
        }
        // 将其他阻塞的线程唤醒，重新争抢锁资源
        notifyAll();
    }

    /**
     * 从队列中 get 取数据
     *
     * @return
     */
    public synchronized String get() throws InterruptedException {
        // 如果队列没有数据，则阻塞
        while (currentValueSize == 0) {
            System.out.println(Thread.currentThread().getName() + "被阻塞");
            wait();
        }
        // 正常执行业务逻辑
        String getValue = queue[getIndex];
        getIndex++;
        currentValueSize--;
        if (getIndex >= queueLength) {
            getIndex = 0;
        }
        // 唤醒其他被阻塞的线程
        notifyAll();
        return getValue;
    }

}
